from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from AskDoctor.models import DoctorModel
from rest_framework import status
from django_redis import get_redis_connection
# Create your views here.

# drf中有用户校验和权限校验

class CartToOrderViews(APIView):
    # 只允许经过验证的用户访问
    permission_classes = [IsAuthenticated,]

    def get(self,request):
        user_id = request.user.id

        redis = get_redis_connection('cart')

        cart_hash = redis.hgetall(f"cart_{user_id}")

        if len(cart_hash) < 1:
            return Response({"message":"购物车中没有数据..."},status=status.HTTP_204_NO_CONTENT)

        cart = [(int(key.decode()),int(value.decode())) for key,value in cart_hash.items()]

        course_id_list = [i[0] for i in cart if i[1] == True]

        course_list = DoctorModel.objects.filter(id__in=course_id_list,is_deleted=False,is_show=True)

        data = []
        for course in course_list:
            data.append(
                {
                    "id": course.id,
                    "name": course.name,
                    "course_cover": "http://127.0.0.1:8000" + course.course_cover.url,
                    "price": course.price,
                    "discount": course.discount,
                    "course_type": course.course_type,
                    "credit": course.credit,
                    # # 判断当前医生是否选中，  cart_hash   cart    1 选中   0  未选中
                    "selected": str(course.id).encode() in cart_hash and cart_hash[
                        str(course.id).encode()].decode() == '1'
                }
            )
        return Response({"message":"购物车选中商品查询成功",'cart':data})








class CartViews(APIView):
    permission_classes = [IsAuthenticated,]
    def post(self,request):
        # 将前端需要添加到购物车中的数据，添加到reids中
        # redis写入数据，redis链接，当前用户
        user_id = request.user.id  #用户id
        # user_id = 1  #用户id
        # 从前端传递的参数中获取医生id
        course_id = request.data.get('course_id')
        # course_id = 1
        # 商品选中状态，默认是1     booler 值    1 true   0 false
        selected = 1
        # 需要判断，医生是否存在,数据库中是否存在医生
        try:
            DoctorModel.objects.get(is_deleted=False,is_show=True,id=course_id)

            # 获取redis链接
            redis = get_redis_connection('cart')
            # 添加医生数据，到redis中
            redis.hset(f"cart_{user_id}",course_id,selected)
            # 添加完成后，获取当前用户的商品总数量
            cart_total = redis.hlen(f"cart_{user_id}")
            return Response({"message":"添加购物车成功","cart_total":cart_total},status=status.HTTP_200_OK)

        except DoctorModel.DoesNotExist:
            print('添加购物车的医生不存在')
            return Response({"message":"医生不存在，添加购物车失败"},status=status.HTTP_400_BAD_REQUEST)

        # redis.hset('cart_{user_id}',医生id,是否选中)
        # return Response()
    def get(self,request):
        # 获取购物车数据
        # 通过用户id，获取对应所有淑
        user_id = request.user.id
        redis = get_redis_connection('cart')
        cart_hash = redis.hgetall(f"cart_{user_id}")

        if len(cart_hash)<1:
            return Response({"message":"购物车中没有数据..."},status=status.HTTP_400_BAD_REQUEST)
        # s = {b'1':b'1',b'2':b'1'}


        # 将redis中获取到的数据，进行转码处理，字典（byte字节）格式数据，转换为  (1，1)数据类型
        cart =[(int(key.decode()),(int(value.decode()))) for key,value in cart_hash.items()]
        # 【（1，1），（2，1），（3，1）】

        # 根据医生id，查询医生信息   id存在于cart中，，将cart中所有的id获取到，并添加到一个新的列表中
        course_id_list = [i[0] for i in cart]

        # 根据医生id列表，查询数据，   id__in 在非连续的范围
        course_list = DoctorModel.objects.filter(is_show=True,is_deleted=False,id__in=course_id_list)

        data = []
        for course in course_list:
            data.append(
                {
                    "id":course.id,
                    "name":course.name,
                    # 获取图片的时候，不会自动添加访问前缀，  http://127.0.0.1:8000/uploads/ /course/course/1.png
                    "course_cover":"http://127.0.0.1:8000"+course.course_cover.url,
                    "price":course.price,
                    "discount":course.discount,
                    "course_type":course.course_type,
                    "credit":course.credit,
                    # 判断当前医生是否选中，  cart_hash   cart    1 选中   0  未选中
                    "selected": str(course.id).encode() in cart_hash and cart_hash[str(course.id).encode()].decode() == '1'
                }
            )

        # 获取redis购物车中的医生id
        # 通过医生id，从数据库中获取医生数据
        # 简化数据，并拼接返回
        return Response({"message":"查询购物车成功",'data':data},status=status.HTTP_200_OK)

    def put(self,request):
        # 修改数据   全部
        # 全选与反选
        user_id = request.user.id
        selected = int(request.data.get('selected', True))
        redis = get_redis_connection('cart')

        cart_hash = redis.hgetall(f"cart_{user_id}")

        if len(cart_hash)< 1:
            return Response({"message": "购物车没有淑，请先添加需要购买的医生"}, status=status.HTTP_200_OK)

        # 修改redis中所有医生的选中状态
        # 3
        # redis.hset(f"cart_{user_id}",医生id)
        # course_id_list =
        cart_id_list = [int(key.decode()) for key in cart_hash]

        # 多次redis操作
        # 开启管道   将redis多个命令，一起打包发送给redis数据库，减少频繁访问的网络通信压力
        pipe = redis.pipeline()
        pipe.multi()

        for i in cart_id_list:
            pipe.hset(f"cart_{user_id}",i,selected)
        pipe.execute()

        return Response({"message": "全选状态修改成功。。。"}, status=status.HTTP_200_OK)


    def patch(self,request):
        # 修改   修改数据的部分
        # 修改购物车中，医生的选中状态
        # 1、获取用户id、获取前端传递的医生id和当前医生状态
        # 2、redis中获取
        # 3、判断、修改数据
        user_id = request.user.id
        course_id = int(request.data.get('course_id',None))
        selected = int(request.data.get('selected',True))

        redis = get_redis_connection('cart')
        # 严谨判断
        try:
            DoctorModel.objects.get(id=course_id,is_deleted=False,is_show=True)
            print('医生存在，修改状态代码继续...')
            redis.hset(f"cart_{user_id}",course_id,selected)
            return Response({"message": "状态修改成功"}, status=status.HTTP_200_OK)
        except DoctorModel.DoesNotExist:
            print('修改的医生不存在')
            redis.hdel(f"cart_{user_id}",course_id)
            return Response({"message": "当前医生不存在，或者以及下架", 'data': ""}, status=status.HTTP_400_BAD_REQUEST)


